﻿

Imports System.IO
Imports System.IO.Compression
Imports System.Net
Imports System.Net.Mail
Imports System.Net.Mail.MailMessage
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Threading
Imports System.Windows.Forms.VisualStyles.VisualStyleElement
Imports System.Xml
Imports iText.Kernel.Pdf
Imports iText.Kernel.Pdf.Canvas
Imports iText.Kernel.Pdf.Canvas.Parser
Imports iText.Kernel.Pdf.Canvas.Parser.Listener
Imports Microsoft.Office.Interop
Imports Microsoft.Office.Interop.Excel
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq







Public Class form_来文表格处理


    <DllImport("user32.dll")>
    Private Shared Function SetForegroundWindow(hWnd As IntPtr) As Boolean
    End Function




    Public Sub New()

        ' 此调用是设计器所必需的。
        InitializeComponent()


        With Label5
            .AutoSize = False          '必须关
            .MaximumSize = New Size(500, 0)
            .Size = New Size(500, 40)   '让系统重新算高
            .Text = "接下来，将 信息框1 中的所有申请号全选复制，在【彼速】中进行批量查询来文，批量输出来文至下方编辑框中文件夹路径中"
        End With


        ' 在 InitializeComponent() 调用之后添加任何初始化。
        txt_目标文件夹路径.AllowDrop = True

        txt_对比文件批量下载本地路径.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "\Edge下载"
        txt_申请文件批量下载本地路径.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "\Edge下载"

        txt_来文汇总路径.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "\temp来文"
        txt_来文汇总路径_维护.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "\temp来文"


        ' 对人员列表进行初始化

        ' 1. 构造 XML 文件完整路径（假设与可执行文件在同一目录）
        Dim xmlPath As String = Path.Combine(System.Windows.Forms.Application.StartupPath, "配置文件", "人员信息.xml")

        Dim persons As New List(Of Person)()


        ' 构建 xml读取器，
        Using xr As XmlReader = XmlReader.Create(xmlPath)

            Dim current As Person = Nothing

            ' 读取 人员信息.xml 文件
            While xr.Read()

                Select Case xr.NodeType

                    Case XmlNodeType.Element
                        If xr.Name = "person" Then
                            current = New Person()
                        ElseIf xr.Name = "name" AndAlso current IsNot Nothing Then
                            current.Name = xr.ReadElementContentAsString()
                        ElseIf xr.Name = "email" AndAlso current IsNot Nothing Then
                            current.Email = xr.ReadElementContentAsString()
                        End If

                    Case XmlNodeType.EndElement
                        If xr.Name = "person" AndAlso current IsNot Nothing Then
                            persons.Add(current)
                            current = Nothing
                        End If



                End Select


            End While


            ' 4. 绑定到 DataGridView
            list_人员列表.AutoGenerateColumns = True
            list_人员列表.DataSource = persons



        End Using





    End Sub


    ' 设置TextBox控件的AllowDrop属性为True

    ' 处理DragEnter事件
    Private Sub DragEnter_编辑框拖放(sender As Object, e As DragEventArgs) Handles txt_目标文件夹路径.DragEnter, txt_来文汇总路径.DragEnter, txt_对比文件批量下载本地路径.DragEnter, txt_申请文件批量下载本地路径.DragEnter, txt_目标文件夹路径_维护.DragEnter, txt_来文汇总路径_维护.DragEnter
        ' 检查拖放的数据是否为文件
        If e.Data.GetDataPresent(DataFormats.FileDrop) Then
            ' 设置拖放效果为复制
            e.Effect = DragDropEffects.Copy
        Else
            ' 如果不是文件，则不允许拖放
            e.Effect = DragDropEffects.None
        End If
    End Sub

    ' 处理DragDrop事件
    Private Sub DragDrop_编辑框拖放(sender As Object, e As DragEventArgs) Handles txt_目标文件夹路径.DragDrop, txt_来文汇总路径.DragDrop, txt_对比文件批量下载本地路径.DragDrop, txt_申请文件批量下载本地路径.DragDrop, txt_目标文件夹路径_维护.DragDrop, txt_来文汇总路径_维护.DragDrop
        ' 获取拖放的文件路径数组
        Dim filePath = CType(e.Data.GetData(DataFormats.FileDrop), String())
        ' 将第一个文件的路径显示在TextBox中
        If filePath.Length > 0 Then
            'txt_目标文件夹路径.Text = filePath(0)
            sender.text = filePath(0)
        End If
    End Sub

    Private Sub btn_处理表格_Click(sender As Object, e As EventArgs) Handles btn_处理表格.Click

        ' 路径编辑框是否为空，若为空，则退出程序
        If txt_目标文件夹路径.Text = "" Then
            MsgBox("路径编辑框不能为空，请将安放有 来文表格 的文件夹拖放到编辑框中！")
            Exit Sub
        End If

        If Path.Exists(txt_目标文件夹路径.Text) Then
            ' 改文件夹名称为当前日期
            If MsgBox("是否将文件夹改名为当前的 年月日 ？", vbYesNo, "修改文件夹名") = vbYes Then


                Dim oldFullPath = txt_目标文件夹路径.Text
                Dim newFolderName = Format(Now, "yyyy年MM月dd日") & "代理老师相关"
                Dim newFullPath = Path.Combine(Path.GetDirectoryName(oldFullPath), newFolderName)

                If oldFullPath <> newFullPath Then

                    If Not Path.Exists(newFullPath) Then

                        Directory.Move(oldFullPath, newFullPath)

                        txt_目标文件夹路径.Text = newFullPath

                        txt_目标文件夹路径.Refresh()

                    Else

                        MsgBox("要修改的文件夹路径已经存在，不能修改！")

                    End If

                End If

            End If
        Else
            MsgBox("路径编辑框中的路径不存在，请重新设置路径！")
            Exit Sub
        End If








        ' 先清空信息框
        txt_信息1.Text = ""
        txt_信息2.Text = ""


        '' 先获取信息框1中的字符串
        'If MsgBox("是否刷新信息框2？", vbYesNo) = vbYes Then
        '    txt_信息2.Text = txt_信息1.Text.TrimEnd({CChar(vbCr), CChar(vbLf), " "c})

        '    Dim arr_临时字符串数组 = txt_信息2.Text.Split(vbCrLf)

        '    Dim result = arr_临时字符串数组.Where(Function(s) s(4) = "1"c).ToList()

        '    txt_信息2.Text = String.Join(vbCrLf, result)

        'End If


        '最终需要在桌面上输出“来文表格检索执行报告.txt”文本文件
        Dim 来文表格检索执行报告 = ""


        Dim excelApp As Object
        Dim excelWorkbook As Object
        Dim excelSheet As Object
        Dim 主操作文件夹路径 = txt_目标文件夹路径.Text ' 假设你有文本框获取文件路径


        Try


            ' 查找文件名包含"来文"的文件（不递归子文件夹）
            Dim files() As String
            files = Directory.GetFiles(主操作文件夹路径, "*来文*.xls*")

            If files.Count <> 1 Then
                MsgBox("文件夹中没有或者存在多个来文表格文件，请确认一下？" & vbCrLf & "本次程序结束执行！", vbInformation)
                Exit Sub
            End If


            'Console.WriteLine(files(0))

            Dim filepath = files(0)


            ' 先做预备工作

            Dim records As New List(Of String())

            ' 复制表头到记录数组的第一行
            records.Add(New String() {"我方文号", "申请号", "案件名称", "文件名称", "发文日期", "申请日", "申请人", "案源人", "代理人", "是否优先审查", "是否快速预审", "原代理人"})  ' 正常运行
            'Dim recordCount As Integer = 0

            ''records_1(i) = arr_直接规定表头(i)


            '' 声明并初始化表头数组
            'Dim arr_直接规定表头 As String() = New String() {"我方文号", "申请号", "案件名称", "文件名称", "发文日期", "申请日", "申请人", "案源人", "代理人", "是否优先审查", "是否快速预审", "原代理人"}

            ' 定义表头序号常量
            Dim 表头序号_我方文号 = 0
            Dim 表头序号_申请号 = 1
            Dim 表头序号_案件名称 = 2
            Dim 表头序号_文件名称 = 3
            Dim 表头序号_发文日期 = 4
            Dim 表头序号_申请日 = 5
            Dim 表头序号_申请人 = 6
            Dim 表头序号_案源人 = 7
            Dim 表头序号_代理人 = 8
            Dim 表头序号_优先审查 = 9
            Dim 表头序号_快速预审 = 10
            Dim 表头序号_原代理人 = 11

            '' 获取表头数量
            'Dim n_表头数 As Integer = arr_直接规定表头.Length

            '' 初始化记录数组 (注意：VB.NET数组默认从0开始，而VBA默认从1开始)
            'Dim records_1(n_表头数 - 1) As String









            ' 尝试创建 Excel 应用实例，类似 VBA 里的 CreateObject("Excel.Application")
            excelApp = CreateObject("Excel.Application")

            ' 若需要可见，可设置，比如调试时设为 True 方便看操作过程
            excelApp.Visible = False

            If filepath <> "" Then
                ' 打开指定工作簿，类似 VBA 里的 Workbooks.Open
                excelWorkbook = excelApp.Workbooks.Open(filepath)
            Else
                MessageBox.Show("请指定一个有效的 Excel 文件路径！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                Exit Sub
            End If

            ' 获取活动工作表，类似 VBA 里的 ActiveSheet
            excelSheet = excelWorkbook.ActiveSheet

            '   **********************************
            '   ***     至此，已经完成了文件  ****
            '   ***     打开                  ****
            '   **********************************


            '' 这里可以添加对工作表的读写操作，示例：读取 A1 单元格值并显示
            'Dim cellValue As Object = excelSheet.Cells(1, 1).Value
            'MessageBox.Show($"A1 单元格的值为：{cellValue}", "结果", MessageBoxButtons.OK, MessageBoxIcon.Information)

            '' 示例：写入数据到 B1 单元格
            'excelSheet.Cells(3, 2).Value = "VB.NET 写入的数据"



            ' 在这里判断第2行的单元格内容是否与“arr_直接规定表头”匹配
            For i = 0 To 10
                ' 进行表头匹配判断（注意：COM对象取值可能为Nothing，需处理）
                Dim cellValue = excelSheet.Cells(2, i + 1).Value
                Dim cellText = If(cellValue Is Nothing, "", cellValue.ToString)



                'If arr_直接规定表头(i) <> cellText Then
                If records(0)(i) <> cellText Then
                    ' 表头不匹配时提示并退出
                    MessageBox.Show("设定表头与实际表头不匹配，程序不能继续执行，请确认后再执行！" & Environment.NewLine & "目前退出程序！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)

                    ' 关闭工作簿和Excel应用
                    excelWorkbook.Close(SaveChanges:=False)
                    excelApp.Quit

                    ' 释放资源
                    Marshal.ReleaseComObject(excelSheet)
                    Marshal.ReleaseComObject(excelWorkbook)
                    Marshal.ReleaseComObject(excelApp)
                    excelSheet = Nothing
                    excelWorkbook = Nothing
                    excelApp = Nothing
                    GC.Collect()

                    Exit Sub
                End If
            Next i

            ' 若匹配无误，修改表头数组中的对应值
            records(0)(9) = "优先审查"
            records(0)(10) = "快速预审"


            'Dim lastRow As Integer = excelSheet.Cells(excelSheet.Rows.Count, 1).End(Excel.XlDirection.xlUp).Row
            Dim lastRow As Integer = excelSheet.UsedRange.Rows.Count


            ' 将 xlsx 表格中所有的内容全部读入到二维数组中

            For rowNumber = 3 To lastRow
                ' 获取单元格值并处理可能的空值
                'Dim cellValue As Object = excelSheet.Cells(rowNumber, 表头序号_代理人+1).Value
                'Dim agentName As String = If(cellValue Is Nothing, "", cellValue.ToString())

                'recordCount += 1

                ' 动态调整二维数组大小（VB.NET中需创建新数组并复制）
                records.Add(New String(11) {})


                ' 复制当前行数据到记录数组
                For colNumber = 0 To UBound(records(0))
                    ' 获取单元格值并处理空值
                    Dim value = excelSheet.Cells(rowNumber, colNumber + 1).Value
                    records(records.Count - 1)(colNumber) = If(value Is Nothing, "", value.ToString)
                Next colNumber

            Next rowNumber






            ' 接下来针对每一“审查意见”或者“补正通知”进行操作
            If MessageBox.Show("是否对审查意见或补正通知书进行检索？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = vbYes Then

                来文表格检索执行报告 = 来文表格检索执行报告 & "开始查找审查意见或补正通知书：" & vbCrLf & vbCrLf

                进度条_1.Minimum = 0
                进度条_1.Maximum = records.Count
                进度条_1.Value = 0
                进度条_1.Step = 1


                For i = 0 To records.Count - 1

                    If InStr(records(i)(表头序号_文件名称), "审查意见") > 0 Or InStr(records(i)(表头序号_文件名称), "补正") > 0 Then

                        'report = report & records_2(i, 表头序号_申请号) & "，" & records_2(i, 表头序号_案件名称) & "：" & vbCrLf
                        来文表格检索执行报告 = 来文表格检索执行报告 & records(i)(表头序号_申请号) & "，" & records(i)(表头序号_案件名称) & "：" & vbCrLf

                        ' 在信息窗口中，将检索得出的所有案件的申请号列出
                        txt_信息1.Text &= records(i)(表头序号_申请号) & vbCrLf

                        ' 判断是否为发明专利，并且不是补正通知，然后将申请号放入到 信息框2 中，准备下载专利文献
                        ' 如果不是发明专利，或者，是补正通知的话，没用公开文件可以下载
                        If records(i)(表头序号_申请号).Substring(4, 1) = 1 And Not records(i)(表头序号_文件名称).Contains("补正") Then
                            txt_信息2.Text &= records(i)(表头序号_申请号) & vbCrLf
                        End If



                        ' 构建文件夹，以“文号”，“申请号”，“代理人”结合作为文件夹名称
                        Dim str_答复文件夹 As String

                        str_答复文件夹 = 主操作文件夹路径 & "\"
                        str_答复文件夹 &= records(i)(表头序号_代理人)
                        str_答复文件夹 &= "_" & records(i)(表头序号_我方文号)
                        str_答复文件夹 &= "_" & Regex.Replace(records(i)(表头序号_申请号), "[^\d]", "")
                        str_答复文件夹 &= "_" & Format(CDate(records(i)(表头序号_发文日期)), "yyyy-MM-dd")

                        ' 以下的代码表示，去除所有的不能用于文件名的字符，诸如斜杠
                        str_答复文件夹 &= "_" & Regex.Replace(records(i)(表头序号_案件名称), "[" & Regex.Escape(New String(Path.GetInvalidFileNameChars)) & "]", "")



                        If Not Directory.Exists(str_答复文件夹) Then
                            Directory.CreateDirectory(str_答复文件夹)
                            'Console.WriteLine("文件夹创建成功")
                        End If


                        ' 在刚刚构建的文件夹中创建一个“案件信息”的文本文件，输出所有的表项内容

                        Dim str_案件信息 = ""

                        str_案件信息 &= "我方文号：" & records(i)(表头序号_我方文号) & vbCrLf
                        str_案件信息 &= "来文名称：" & records(i)(表头序号_文件名称) & vbCrLf
                        str_案件信息 &= "申请号：" & records(i)(表头序号_申请号) & vbCrLf
                        str_案件信息 &= "案件名称：" & records(i)(表头序号_案件名称) & vbCrLf
                        str_案件信息 &= "发文日期：" & records(i)(表头序号_发文日期) & vbCrLf
                        str_案件信息 &= "申请日：" & records(i)(表头序号_申请日) & vbCrLf
                        str_案件信息 &= "申请人：" & records(i)(表头序号_申请人) & vbCrLf
                        str_案件信息 &= "维护人：" & records(i)(表头序号_案源人) & vbCrLf
                        str_案件信息 &= "代理人：" & records(i)(表头序号_代理人) & vbCrLf
                        str_案件信息 &= "优先审查：" & records(i)(表头序号_优先审查) & vbCrLf
                        str_案件信息 &= "快速预审：" & records(i)(表头序号_快速预审) & vbCrLf
                        str_案件信息 &= "原代理人：" & records(i)(表头序号_原代理人) & vbCrLf

                        File.WriteAllText(Path.Combine(str_答复文件夹, "案件信息.txt"), str_案件信息, Encoding.UTF8)

                    End If

                    进度条_1.PerformStep()

                Next

            End If


            File.WriteAllText(主操作文件夹路径 & "\来文表格检索执行报告.txt", 来文表格检索执行报告, Encoding.UTF8)

        Catch ex As Exception
            MessageBox.Show($"操作过程中出现错误：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            ' 释放资源，非常关键，避免 COM 对象残留导致问题
            If excelSheet IsNot Nothing Then
                Marshal.ReleaseComObject(excelSheet)
                excelSheet = Nothing
            End If
            If excelWorkbook IsNot Nothing Then
                excelWorkbook.Close
                Marshal.ReleaseComObject(excelWorkbook)
                excelWorkbook = Nothing
            End If
            If excelApp IsNot Nothing Then
                excelApp.Quit
                Marshal.ReleaseComObject(excelApp)
                excelApp = Nothing
            End If
            GC.Collect() ' 强制垃圾回收，协助释放资源

            MsgBox("完成全部表格信息处理！", vbInformation)

        End Try

        sender.ForeColor = Color.Red

    End Sub



    Public Sub ReadWriteExcelWithInterop()
        'Dim excelApp As New Excel.Application()
        'Dim workbook As Excel.Workbook
        'Dim worksheet As Excel.Worksheet

        'Try
        '    ' 打开现有文件
        '    workbook = excelApp.Workbooks.Open(txt_周三表格路径.Text)
        '    worksheet = workbook.Sheets(1) ' 获取第一个工作表

        '    ' 读取数据
        '    Dim cellValue As String = worksheet.Cells(1, 1).Value2.ToString()
        '    Console.WriteLine($"A1单元格的值: {cellValue}")

        '    ' 写入数据
        '    worksheet.Cells(1, 2).Value2 = "新数据"

        '    ' 保存更改
        '    workbook.Save()

        '    Console.WriteLine("操作完成!")

        'Catch ex As Exception
        '    Console.WriteLine($"错误: {ex.Message}")
        'Finally
        '    ' 释放资源
        '    workbook?.Close()
        '    excelApp?.Quit()

        '    ' 强制垃圾回收
        '    System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheet)
        '    System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook)
        '    System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp)
        '    worksheet = Nothing
        '    workbook = Nothing
        '    excelApp = Nothing
        '    GC.Collect()
        'End Try
    End Sub

    Private Sub btn_分配来文_Click(sender As Object, e As EventArgs) Handles btn_分配来文.Click

        ' 路径编辑框是否为空，若为空，则退出程序
        If txt_来文汇总路径.Text = "" Then
            MsgBox("路径编辑框不能为空，请将安放有 来文PDF文档 的文件夹拖放到编辑框中！")
            Exit Sub
        End If


        ' 将指定文件夹中的来文分配到每个审查意见文件包裹中

        ' 遍历目标文件夹中的每一个文件夹

        Try

            Dim 来文分配执行报告 = ""

            Dim dir_目标文件夹 As New DirectoryInfo(txt_目标文件夹路径.Text)
            Dim subDirs = dir_目标文件夹.GetDirectories


            进度条_1.Minimum = 0
            进度条_1.Maximum = subDirs.Count
            进度条_1.Value = 0
            进度条_1.Step = 1

            For Each subDir In subDirs

                ' 解析文件夹名，获取我方文号，申请号，等等信息


                Dim arrstr = Split(subDir.Name, "_")

                Dim temp_代理人 = arrstr(0)
                Dim temp_我方文号 = arrstr(1)
                Dim temp_申请号 = arrstr(2)
                Dim temp_发文日期 = arrstr(3)

                来文分配执行报告 &= "关于我方文号 " & temp_我方文号 & "：" & vbCrLf


                ' 根据我方文号来查找来文的文件夹
                Dim dir_来文汇总 As New DirectoryInfo(txt_来文汇总路径.Text)
                Dim subdirs_来文汇总 = dir_来文汇总.GetDirectories(temp_我方文号)

                If subdirs_来文汇总.Length > 0 Then

                    Dim files = subdirs_来文汇总(0).GetFiles

                    ' 遍历文件夹中的每一个文件
                    For Each file In files
                        ' 将该文件夹中发文日期与当前文件夹相匹配的PDF文件复制到审查意见文件包裹中

                        If Split(file.Name, "_")(1) = temp_发文日期 Then
                            file.CopyTo(Path.Combine(subDir.FullName, file.Name), overwrite:=True)
                        ElseIf file.Name.IndexOf("补正") >= 0 Then
                            file.CopyTo(Path.Combine(subDir.FullName, file.Name), overwrite:=True)
                            System.IO.File.Create(Path.Combine(subDir.FullName, "先前有补正")).Close()
                        End If

                    Next

                Else
                    ' 未找到匹配的文件夹
                    MsgBox("" & "关于我方文号" & temp_我方文号 & "，" & "没有找到匹配文件夹，请确认一下", vbExclamation)
                    来文分配执行报告 &= "没有找到匹配文件夹，请确认一下!" & vbCrLf

                End If

                来文分配执行报告 &= vbCrLf


                进度条_1.PerformStep()

            Next

            File.WriteAllText(txt_目标文件夹路径.Text & "\来文分配执行报告.txt", 来文分配执行报告, System.Text.Encoding.UTF8)

        Catch ex As Exception
            MsgBox("错误: " & ex.Message, vbExclamation)
        End Try

        MsgBox("完成全部来文分配操作！")

        sender.ForeColor = Color.Red

    End Sub

    Private Sub btn_提取公开号信息_Click(sender As Object, e As EventArgs) Handles btn_提取公开号信息.Click
        'MsgBox("测试一下")

        ' 清空信息框2
        txt_信息2.Text = ""

        ' 先获取信息框1中的字符串
        Dim str_临时字符串1 = txt_信息1




        ' 目前，以下的正则表达式比较准
        Dim matches = Regex.Matches(str_临时字符串1.Text, "\t(\d+)\s+\[([^\]]+)\]\s+(.+?)\s-\s([A-Z]{2,3}\d+[^;]*);\s*([^;\s]+)")

        'Dim matches = Regex.Matches(str_临时字符串1.Text, "\t(\d+)\s+\[([^\]]+)\]\s+([^-]+?)\s-\s([^;]+);\s*([^;\s]+)")
        'Dim matches = Regex.Matches(str_临时字符串1.Text, "\t(\d+)\s+\[(.*?)\].*?\s-\s.*?;\s*(.*)")
        'Dim matches = Regex.Matches(str_临时字符串1.Text, "\t\d+\s\[.*?\].*?\s-\s.*?;\s.*?\s")
        For Each match As Match In matches

            'txt_信息2.Text &= $"找到匹配项：{match.Value}" & vbCrLf
            'txt_信息2.Text &= $"序号：{match.Groups(1).Value}" & vbCrLf
            'txt_信息2.Text &= $"地区组织：{match.Groups(2).Value}" & vbCrLf
            'txt_信息2.Text &= $"发明名称：{match.Groups(3).Value}" & vbCrLf
            'txt_信息2.Text &= $"申请号：{match.Groups(4).Value}" & vbCrLf
            'txt_信息2.Text &= $"公开号：{match.Groups(5).Value}" & vbCrLf

            'txt_信息2.Text &= vbCrLf

            txt_信息2.Text &= $"{match.Groups(4).Value}：{match.Groups(5).Value}" & vbCrLf


            'txt_信息2.Text &= $"找到匹配项：{match.Value}，位置：{match.Index}" & vbCrLf
            'txt_信息2.Text &= $"找到匹配项：{match.Groups(1).Value}，位置：{match.Index}" & vbCrLf
            'txt_信息2.Text &= $"测试：{match.Groups(2).Value}，位置：{match.Groups(2).Index}" & vbCrLf
            'Console.WriteLine($"找到匹配项：{match.Value}，位置：{match.Index}")
        Next

        sender.ForeColor = Color.Red

    End Sub

    Private Sub btn_批量下载专利_Click(sender As Object, e As EventArgs) Handles btn_批量下载专利.Click

        ' 先获取信息框2中的字符串
        Dim str_临时字符串1 = txt_信息2.Text

        ' 去除字符串末尾的无效字符
        'str_临时字符串1 = System.Text.RegularExpressions.Regex.Replace(str_临时字符串1, "\s+$", "")
        str_临时字符串1 = str_临时字符串1.TrimEnd({CChar(vbCr), CChar(vbLf), " "c})


        Dim arr_号码组 = str_临时字符串1.Split({vbCrLf, vbCr, vbLf}, StringSplitOptions.None)

        Dim 本地下载路径 = txt_对比文件批量下载本地路径.Text


        Dim 重定向地址 = ""
        Dim 重定向地址组 = ""
        Dim 下载状况报告 = ""

        Dim 下载案件成功数量 = 0
        Dim 下载案件失败数量 = 0


        进度条_1.Minimum = 0
        进度条_1.Maximum = arr_号码组.Count
        进度条_1.Value = 0
        进度条_1.Step = 1


        For Each 号码 In arr_号码组

            Dim 申请号 = 号码.Split("：")(0)
            Dim 公开号 = 号码.Split("：")(1)

            ' edge浏览器 打开路径
            Dim edgePath = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"

            ' 分国内和国外两部分来处理

            If 申请号.StartsWith("CN", StringComparison.Ordinal) Then
                ' 国内案件处理

                ' 用申请号来组织下载地址
                Dim 下载地址 = "https://pro.soopat.com/Chinese/GetPdf?sqh=" & 申请号 & "&sqgk=0&line=0"


                ' 采用 edge浏览器 打开“下载地址”
                If File.Exists(edgePath) Then
                    Process.Start(edgePath, 下载地址)

                    Do
                        For i = 0 To 100
                            ' 等待文件夹中出现以当前申请号开头的 PDF 文件
                            Dim 匹配文件 = Directory.GetFiles(本地下载路径, 申请号 & "*")

                            If 匹配文件.Length > 0 Then

                                ' 找到了，
                                下载案件成功数量 += 1
                                txt_信息2.Text = txt_信息2.Text.Replace(号码 & vbCrLf, "")

                                ' 退出当前循环
                                Exit Do
                            Else
                                Thread.Sleep(100)
                            End If
                            'If File.Exists(文件路径) AndAlso 文件是否可访问(文件路径) Then
                            '    ' 再等待一小段时间确保文件完全写入
                            '    Thread.Sleep(1000)
                            '    Return True
                            'End If
                        Next i

                        If MsgBox("是否继续等待", vbYesNo Or vbQuestion) = vbNo Then

                            下载状况报告 &= "下载申请号公开号为  " & 号码 & " 的专利文献失败！" & vbCrLf
                            下载案件失败数量 += 1

                            MsgBox("请立即激活浏览器窗口！", vbInformation)

                            Thread.Sleep(3000)  ' 等待 1 秒（可根据网络调整）
                            ' 发送Ctrl+W组合键关闭当前标签页
                            SendKeys.Send("^(w)")

                            Exit Do

                        End If
                    Loop

                Else
                    ' 若找不到 Edge 路径，使用默认浏览器
                    MsgBox("无法打开edge浏览器")
                End If

            Else
                ' 国外案件处理

                ' 用公开号来组织下载地址

                Dim 初始下载地址 = "https://pro.soopat.com/World/GetPdf?PN=" & Uri.EscapeDataString(公开号)

                ' 启动 Edge 浏览器
                If Not File.Exists(edgePath) Then
                    MsgBox("无法找到 Edge 浏览器", vbInformation)
                    Exit Sub
                End If

                Dim edgeProcess = Process.Start(edgePath, 初始下载地址)
                If edgeProcess Is Nothing Then
                    MsgBox("启动 Edge 失败", vbInformation)
                    Exit Sub
                End If

                Try
                    ' 等待浏览器启动并完成重定向
                    Console.WriteLine("等待浏览器加载...")
                    Thread.Sleep(2000)  ' 等待 5 秒（可根据网络调整）

                    ' 激活 Edge 窗口
                    'If Not SetForegroundWindow(edgeProcess.MainWindowHandle) Then
                    '    MsgBox("无法激活 Edge 窗口")
                    '    Return
                    'End If


                    ' 获取重定向地址
                    Dim 计数 = 0

                    Do
                        计数 += 1
                        ' 模拟键盘操作获取地址栏 URL
                        重定向地址 = 获取地址栏URL()

                        ' 判断一下地址栏内的地址是否已经重定向了
                        If 重定向地址 = "" Then
                            MsgBox("在下载申请号公开号为 " & 号码 & " 的专利文献时失败，没有下载成功！", vbExclamation)
                            下载状况报告 &= "下载公开号为  " & 号码 & " 的专利文献失败！" & vbCrLf
                            Continue For
                        End If

                        ' 若重定向地址还没有出现，则继续等待
                        If 重定向地址 = 初始下载地址 Then

                            If 计数 < 10 Then
                                Thread.Sleep(200)  ' 等待 1 秒（可根据网络调整）
                            Else
                                If MsgBox("重定向还没有成功，是否继续等待？", vbYesNo Or vbInformation) = vbYes Then
                                    计数 = 0
                                    MsgBox("请立即激活浏览器窗口！")
                                    Thread.Sleep(3000)  ' 等待 1 秒（可根据网络调整）
                                Else
                                    下载状况报告 &= "下载申请号公开号为  " & 号码 & " 的专利文献失败！" & vbCrLf
                                    下载案件失败数量 += 1

                                    MsgBox("请立即激活浏览器窗口！")

                                    Thread.Sleep(3000)  ' 等待 1 秒（可根据网络调整）
                                    ' 发送Ctrl+W组合键关闭当前标签页
                                    SendKeys.Send("^(w)")

                                    Continue For
                                End If
                            End If
                        Else

                            ' 发送Ctrl+W组合键关闭当前标签页
                            SendKeys.Send("^(w)")

                            Exit Do

                        End If

                    Loop

                    ' 只要能够正常出 DO LOOP 循环的，一定是重定向成功了

                    ' 接下来开始下载重定向后的地址

                    ' 创建 WebClient 实例用于下载文件
                    Using client As New WebClient

                        ' 组织文件保存名称
                        Dim fileName = 公开号 & "_" & 申请号 & ".pdf"

                        Dim filePath = Path.Combine(本地下载路径, fileName)

                        ' 下载 PDF 文件
                        client.DownloadFile(重定向地址, filePath)


                        下载案件成功数量 += 1

                        txt_信息2.Text = txt_信息2.Text.Replace(号码 & vbCrLf, "")

                    End Using




                    '        ' 组织文件保存名称
                    '        Dim fileName = $"{公开号}_{申请号}.pdf"
                    '        Dim filePath = Path.Combine(本地下载路径, fileName)

                    '        Try
                    '            Using response As HttpResponseMessage = Await client.GetAsync(重定向地址, HttpCompletionOption.ResponseHeadersRead)

                    'response.EnsureSuccessStatusCode()

                    '                Using fs As New FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)
                    '                    Await response.Content.CopyToAsync(fs)
                    'End Using
                    '            End Using

                    '            ' 下载成功后的业务处理
                    '            下载案件成功数量 += 1
                    '            txt_信息2.Text = txt_信息2.Text.Replace(号码 & vbCrLf, "")

                    '        Catch ex As Exception
                    '            ' 可按需记录日志或弹窗提示
                    '            MessageBox.Show($"下载失败：{ex.Message}")
                    '        End Try




                Catch ex As Exception
                    MsgBox($"操作失败：{ex.Message}")
                Finally
                    ' 可选：关闭浏览器（若无需用户交互）
                    ' edgeProcess.Kill()
                End Try


            End If

            进度条_1.PerformStep()

        Next

        下载状况报告 &= vbCrLf
        下载状况报告 &= "成功下载案件数量：" & 下载案件成功数量 & vbCrLf
        下载状况报告 &= "下载案件失败数量：" & 下载案件失败数量 & vbCrLf



        File.WriteAllText(本地下载路径 & "\下载状况报告" & Now.ToString("yyyyMMddHHmmss") & ".txt", 下载状况报告, Encoding.UTF8)


        MsgBox($"完成批量下载！{vbCrLf}是否对下载的文件重命名？", vbYesNo Or vbInformation)


        ' 接下来，根据 “arr_号码组” 对所有下载的文件进行改名，将公开号前缀至文件名

        'Dim 本地下载路径 = txt_对比文件批量下载本地路径.Text


        For Each f In Directory.GetFiles(本地下载路径)

            Dim oldName = Path.GetFileName(f)

            Dim str_前缀名 = oldName.Split("-")(0)

            For Each 号码 In arr_号码组
                Dim 申请号 = 号码.Split("：")(0)

                If str_前缀名 = 申请号 Then

                    Dim 公开号 = 号码.Split("：")(1)

                    Dim newPath = Path.Combine(本地下载路径, 公开号 & "_" & oldName)


                    '防止重名冲突
                    If Not File.Exists(newPath) Then
                        File.Move(f, newPath)
                    End If

                    Exit For

                End If

            Next

        Next

        MsgBox("完成对比文件的批量下载，请参阅下载状况报告！", vbInformation)

        sender.ForeColor = Color.Red

    End Sub



    Private Function 获取地址栏URL(Optional 重试次数 As Integer = 3) As String
        For i As Integer = 1 To 重试次数
            Try
                ' 聚焦地址栏
                SendKeys.SendWait("%d")
                Thread.Sleep(50)

                ' 全选并复制
                SendKeys.SendWait("^(a)")
                Thread.Sleep(50)

                SendKeys.SendWait("^(c)")
                Thread.Sleep(50)

                SendKeys.SendWait("{ESC}")
                Thread.Sleep(50)

                SendKeys.SendWait("{ESC}")
                Thread.Sleep(50)

                ' 获取剪贴板内容
                Dim url = Clipboard.GetText()

                ' 验证 URL 是否有效
                If Not String.IsNullOrEmpty(url) AndAlso url.StartsWith("http") Then
                    Return url
                End If

                Console.WriteLine($"尝试 {i}/{重试次数} 失败，URL 无效：{url}")
                Thread.Sleep(1000)  ' 等待 1 秒后重试
            Catch ex As Exception
                Console.WriteLine($"尝试 {i}/{重试次数} 异常：{ex.Message}")
            End Try
        Next

        Return ""  ' 所有重试均失败

    End Function

    Private Sub btn_提取来文信息_Click(sender As Object, e As EventArgs) Handles btn_提取来文信息.Click

        ' 针对目标文件夹，遍历其中的每一个文件夹


        ' 路径编辑框是否为空，若为空，则退出程序
        If Me.txt_目标文件夹路径.Text = "" Then
            MsgBox("目标文件夹路径编辑框不能为空，请将安放有 所有代理人案件信息 的文件夹拖放到编辑框中！")
            Exit Sub
        End If


        ' 先获取目标文件夹下的所有文件夹

        Dim obj_目标文件夹 As New DirectoryInfo(txt_目标文件夹路径.Text)
        Dim subDirs = obj_目标文件夹.GetDirectories

        Dim str_所有对比文件公开号 = ""
        Dim str_优先审查案件记录 = $"优先审查案件：{vbCrLf}"


        进度条_1.Minimum = 0
        进度条_1.Maximum = subDirs.Count
        进度条_1.Value = 0
        进度条_1.Step = 1


        For Each subDir In subDirs

            ' 遍历子文件夹中的每一个文件，
            ' 找到发文日期与子文件夹名称中的发文日期相同的 pdf文件，
            ' 再判断“审查意见”和“补正通知”，
            ' 然后将找到的 pdf文件 转换为文本文件
            ' 在此过程中，将检索到的所有对比文件的信息做成报告，
            ' 将所有对比文件的公开号汇总列表，形成报告，最后复制到 信息框2 中

            Dim arr_文件夹名称信息组合 = subDir.Name.Split("_")

            ' 遍历每一个文件
            Dim files = subDir.GetFiles().Where(Function(f) f.Extension.Equals(".pdf", StringComparison.OrdinalIgnoreCase) AndAlso (f.Name.Contains("审查意见") OrElse f.Name.Contains("补正通知"))).ToArray()
            'Dim files = subDir.GetFiles().Where(Function(f) f.Name.Contains("审查意见") OrElse f.Name.Contains("补正通知")).ToArray()
            For Each file In files

                'MsgBox(file.ToString)

                Dim arr_文件名称信息组合 = file.Name.Split("_")

                ' 对比两者的“发文日期”是否相同
                If CDate(arr_文件名称信息组合(1)) = CDate(arr_文件夹名称信息组合(3)) Then

                    ' 自此，确定的要提取信息的文件

                    ' 将 pdf文件 转换为文本文件，并保存在当前的文件夹中

                    Dim 文本文件存储路径 = file.DirectoryName

                    Dim sb As New StringBuilder()

                    Using pdfDoc As New PdfDocument(New PdfReader(file.FullName))
                        For page As Integer = 1 To pdfDoc.GetNumberOfPages()
                            Dim strategy = New LocationTextExtractionStrategy()
                            sb.AppendLine(PdfTextExtractor.GetTextFromPage(pdfDoc.GetPage(page), strategy))
                        Next
                    End Using


                    Dim str_通知书文本 = sb.ToString()

                    System.IO.File.WriteAllText(文本文件存储路径 & "\" & file.Name & ".txt", str_通知书文本, Encoding.UTF8)


                    ' 接下来，从提取的字符串中获取相关信息，主要是对比文件信息


                    ' 获取对比文件信息

                    Dim json_对比文件信息 = fun_提取对比文件信息(str_通知书文本)



                    ' 这里需要应对一个特殊的情况，美国的申请，其公开号需要在第5位加一个零
                    ' 解析并原地修改
                    Dim arr As JArray = JArray.Parse(json_对比文件信息)
                    For Each item As JObject In arr
                        Dim pubNo As String = item("公开号").ToString()
                        If pubNo.StartsWith("US", StringComparison.OrdinalIgnoreCase) Then
                            Dim digits As String = pubNo.Substring(2)
                            If digits.Length < 13 Then
                                digits = digits.Insert(4, "0")
                                item("公开号") = "US" & digits
                            End If
                        End If
                    Next

                    ' 更新字符串变量
                    json_对比文件信息 = arr.ToString(Newtonsoft.Json.Formatting.None)   ' 或 Formatting.Indented 如需换行


                    ' 这里收到的是 json 格式的字符串
                    System.IO.File.WriteAllText(文本文件存储路径 & "\对比文件信息.json", json_对比文件信息, Encoding.UTF8)

                    Dim list_对比文件信息 = JArray.Parse(json_对比文件信息).Select(Function(t) t("公开号").ToString()).ToList()
                    'Dim str_本案对比文件公开号 = String.Join(vbCrLf, list_对比文件信息)
                    Dim str_本案对比文件公开号 As String = String.Join(vbCrLf, list_对比文件信息.Where(Function(s) Not String.IsNullOrWhiteSpace(s)))

                    System.IO.File.WriteAllText(文本文件存储路径 & "\对比文件公开号列表.txt", str_本案对比文件公开号, Encoding.UTF8)

                    If str_本案对比文件公开号 <> "" Then
                        str_所有对比文件公开号 &= str_本案对比文件公开号 & vbCrLf
                    End If



                    ' 接下来，检查是否为优先审查

                    If Regex.IsMatch(str_通知书文本, "优\s*先\s*审\s*查") Then
                        ' 在当前的文件夹中新建一个文本文件“优先审查”
                        System.IO.File.Create(Path.Combine(subDir.FullName, "优先审查")).Close()   ' 别忘了 Close，否则句柄占用
                        str_优先审查案件记录 &= subDir.Name.Split("_")(0) & vbTab & subDir.Name.Split("_")(2) & vbCrLf
                    End If



                    ' 最后退出查找文件的循环
                    Exit For

                End If
            Next

            进度条_1.PerformStep()

        Next

        str_所有对比文件公开号 = str_所有对比文件公开号.TrimEnd({CChar(vbCr), CChar(vbLf), " "c})

        System.IO.File.WriteAllText(obj_目标文件夹.FullName & "\所有对比文件公开号列表.txt", str_所有对比文件公开号, Encoding.UTF8)
        System.IO.File.WriteAllText(obj_目标文件夹.FullName & "\优先审查案件记录.txt", str_优先审查案件记录, Encoding.UTF8)

        ' 送入到 信息框2 中
        txt_信息2.Text = str_所有对比文件公开号

        MsgBox("完成全部来文信息提取操作！")

        sender.ForeColor = Color.Red

    End Sub





    ''' <summary>
    ''' 从任意 OA 文本中提取所有“对比文件”信息
    ''' </summary>
    ''' <param name="oaText">OA 全文字符串</param>
    ''' <returns>JSON 字符串</returns>
    Public Shared Function fun_提取对比文件信息(oaText As String) As String
        ' 正则覆盖：专利/申请号、公开日、期刊/学位论文、arXiv 等


        Dim pattern As String = "
    对比文件\s*(?:(?<序号>\d+)\s*)?[\(（【]?\s*
    (?:
       (?<公开号>[A-Z]{2}(?:\d+[A-Z]?\d*)+)\s*(?:,\s*公开日[：:]?\s*(?<公开日>\d{4}\s*年\s*\d{1,2}\s*月\s*\d{1,2}\s*日))?
     |
       \u201C(?<中文标题>[^\u201D]+)\u201D[^）】)]*?，\s*(?<中文作者>[^，]+).*?(?<中文年份>\d{4})\s*年.*?(?<中文月>\d{1,2})\s*月.*?(?<中文日>\d{1,2})\s*日
     |
       (?<学位论文>[^，]+，\s*(?<学位作者>[^，]+)，.*?中国优秀.*?学位论文.*?，(?<学位年>\d{4})\s*年.*?(?<学位月>\d{1,2})\s*月.*?(?<学位日>\d{1,2})\s*日)
     |
       \u201C(?<英文Title>[^\u201D]+)\u201D[^，]*?，\s*(?<英文Author>[^，]+).*?(?<英文Year>\d{4})\s*年.*?(?<英文Month>\d{1,2})\s*月.*?(?<英文Day>\d{1,2})\s*日
    )
    [\)）】]?
"

        pattern = Regex.Replace(pattern, "\s+", " ", RegexOptions.None)

        Dim rx As New Regex(pattern, RegexOptions.IgnorePatternWhitespace Or RegexOptions.Compiled)



        ' 去重：用 Dictionary 以 公开号+文献标题 为键
        Dim dict As New Dictionary(Of String, Object)
        For Each m As Match In rx.Matches(oaText)
            Dim id = m.Groups("公开号").Value.Trim & "|" &
                     (m.Groups("中文标题").Value.Trim &
                      m.Groups("英文Title").Value.Trim &
                      m.Groups("学位论文").Value.Trim)
            If Not dict.ContainsKey(id) Then
                dict.Add(id, New With {
                    .序号 = m.Groups("序号").Value.Trim,
                    .公开号 = m.Groups("公开号").Value.Trim,
                    .公开日 = m.Groups("公开日").Value.Trim,
                    .文献标题 = If(m.Groups("中文标题").Success, m.Groups("中文标题").Value.Trim,
                                   If(m.Groups("英文Title").Success, m.Groups("英文Title").Value.Trim,
                                   If(m.Groups("学位论文").Success, m.Groups("学位论文").Value.Trim, ""))),
                    .作者 = If(m.Groups("中文作者").Success, m.Groups("中文作者").Value.Trim,
                               If(m.Groups("英文Author").Success, m.Groups("英文Author").Value.Trim,
                               If(m.Groups("学位作者").Success, m.Groups("学位作者").Value.Trim, ""))),
                    .年份 = If(m.Groups("中文年份").Success, m.Groups("中文年份").Value.Trim,
                               If(m.Groups("英文Year").Success, m.Groups("英文Year").Value.Trim,
                               If(m.Groups("学位年").Success, m.Groups("学位年").Value.Trim, ""))),
                    .类型 = If(m.Groups("公开号").Success, "PATENT",
                               If(m.Groups("中文标题").Success Or m.Groups("英文Title").Success, "ARTICLE", "THESIS"))
                })
            End If
        Next
        Return JsonConvert.SerializeObject(dict.Values, Newtonsoft.Json.Formatting.Indented)


    End Function

    Private Sub 分配对比文件(sender As Object, e As EventArgs) Handles btn_分配对比文件.Click


        ' 路径编辑框是否为空，若为空，则退出程序
        If txt_对比文件批量下载本地路径.Text = "" Then
            MsgBox("对比文件批量下载本地路径编辑框不能为空，请将下载有 对比文件 的文件夹拖放到编辑框中！")
            Exit Sub
        End If


        ' 路径编辑框是否为空，若为空，则退出程序
        If txt_目标文件夹路径.Text = "" Then
            MsgBox("目标文件夹路径编辑框不能为空，请将安放有 所有代理人案件信息 的文件夹拖放到编辑框中！")
            Exit Sub
        End If


        ' 将指定文件夹中的对比文件分配到每个审查意见文件包裹中

        ' 遍历目标文件夹中的每一个文件夹

        Try

            Dim 对比文件分配执行报告 = ""

            Dim dir_对比文件的本地下载地址路径 As New DirectoryInfo(txt_对比文件批量下载本地路径.Text)
            Dim 对比文件组 = dir_对比文件的本地下载地址路径.GetFiles


            Dim dir_目标文件夹 As New DirectoryInfo(txt_目标文件夹路径.Text)
            Dim subDirs = dir_目标文件夹.GetDirectories

            进度条_1.Minimum = 0
            进度条_1.Maximum = subDirs.Count
            进度条_1.Value = 0
            进度条_1.Step = 1

            For Each subDir In subDirs

                Dim str_json文件全路径 = Path.Combine(subDir.FullName, "对比文件信息.json")

                If Not File.Exists(str_json文件全路径) Then
                    MsgBox("在给 " & subDir.Name & " 分配对比文件时，没有找到 对比文件信息.json 文件，请确认一下！", vbInformation)
                    Continue For
                    ' 文件存在
                End If


                ' 提取 json文件 中的对比文件信息

                '1. 读取 JSON 文本
                Dim json = File.ReadAllText(str_json文件全路径)

                '2. 解析
                Dim arr = JArray.Parse(json)

                '3. 遍历输出
                For Each item As JObject In arr
                    Dim 序号 = item("序号").ToString
                    Dim 公开号 = item("公开号").ToString

                    If 公开号 = "" Then
                        Continue For
                    End If

                    ' 用公开号来查对比文件
                    For Each 对比文件 In 对比文件组

                        If 对比文件.Name Like 公开号 & "*" Then
                            对比文件.CopyTo(Path.Combine(subDir.FullName, "（对比文件" & 序号 & "）" & 对比文件.Name), True)

                            'System.IO.File.Copy(sourceFileName:=对比文件, destFileName:="E:\Backup\abc.txt", overwrite:=True)

                        End If

                    Next

                Next

                进度条_1.PerformStep()

            Next

            File.WriteAllText(txt_目标文件夹路径.Text & "\对比文件分配执行报告.txt", 对比文件分配执行报告, Encoding.UTF8)

        Catch ex As Exception
            MsgBox("错误: " & ex.Message, vbExclamation)
        End Try

        MsgBox("完成全部对比文件分配操作！")

        sender.ForeColor = Color.Red

    End Sub

    Private Sub btn_下载初始申请稿_Click(sender As Object, e As EventArgs) Handles btn_下载初始申请稿.Click

        ' 路径编辑框是否为空，若为空，则退出程序
        If txt_目标文件夹路径.Text = "" Then
            MsgBox("目标文件夹路径编辑框不能为空，请将安放有 所有代理人案件信息 的文件夹拖放到编辑框中！")
            Exit Sub
        End If


        ' 遍历目标文件夹中的每一个文件夹

        Try

            Dim 初始申请稿下载执行报告 = ""

            ' 先组织共享服务器地址

            Dim str_共享服务器 = "\\1-pc\伯瑞杰共享中心\"

            Dim str_电子申请文件路径 = Path.Combine(str_共享服务器, "电子申请")



            Dim dir_目标文件夹 As New DirectoryInfo(txt_目标文件夹路径.Text)
            Dim subDirs = dir_目标文件夹.GetDirectories

            Dim str_申请稿文件夹路径 = ""


            '进度条_1.Value =
            进度条_1.Minimum = 0
            进度条_1.Maximum = subDirs.Count
            进度条_1.Value = 0
            进度条_1.Step = 1



            'Dim counter As Integer = 0

            For Each subDir In subDirs

                'counter += 1

                'lab_下载申请稿计数.Text = counter.ToString

                'lab_下载申请稿计数.Refresh()          '立即重绘控件
                'Application.DoEvents()               '让 UI 线程处理一次消息队列

                ' 先根据申请号，获取申请年份

                Dim 申请年份 = subDir.Name.Split("_")(2).Substring(0, 4)

                If 申请年份 = Now.Year Then

                    'str_申请稿文件夹路径 = Path.Combine(str_电子申请文件路径 & "\" & Now.Year)
                    str_申请稿文件夹路径 = Path.Combine(str_电子申请文件路径, 申请年份 & "年电子申请")

                Else
                    'str_申请稿文件夹路径 = Path.Combine(str_电子申请文件路径 & "\" & Now.Year)
                    str_申请稿文件夹路径 = Path.Combine(str_电子申请文件路径, "往年专利存档文件", 申请年份)

                End If

                If 申请年份 = 2024 Or 申请年份 >= 2018 And 申请年份 <= 2022 Then
                    str_申请稿文件夹路径 &= "年存档"
                End If


                If 申请年份 = 2023 Then
                    str_申请稿文件夹路径 &= "年电子申请"
                End If


                'If 申请年份 = 2024 Or (申请年份 >= 2012 And 申请年份 <= 2017) Then
                If 申请年份 = 申请年份 >= 2012 And 申请年份 <= 2017 Then
                    str_申请稿文件夹路径 &= "存档"
                End If



                If 申请年份 = 2024 Or 申请年份 >= 2017 And 申请年份 <= 2022 Then
                    str_申请稿文件夹路径 &= "\" & 申请年份 & "年电子申请"
                End If


                str_申请稿文件夹路径 &= "\" & "【已提交】电子申请"

                ' 测试一下，文件夹路径是否存在
                If Not Directory.Exists(str_申请稿文件夹路径) Then
                    MsgBox("文件夹不存在，请重新修改程序", vbExclamation)
                    Exit Sub
                End If

                ' \\1-pc\伯瑞杰共享中心\电子申请\往年专利存档文件\2024年存档\2024年电子申请

                Dim dir_申请稿文件夹 As New DirectoryInfo(str_申请稿文件夹路径)

                ' 自此完成了 文件夹路径 的组织

                ' 接下来，在“str_申请稿文件夹路径”中查找符合发明名称的案子，找到了就下载，没有找到的话就算了

                For Each file In dir_申请稿文件夹.GetFiles("*" & subDir.Name.Split("_")(4) & "*")

                    file.CopyTo(Path.Combine(subDir.FullName, "（原提交申请稿）" & file.Name), True)

                Next

                进度条_1.PerformStep()
                '进度条_1.Refresh()

            Next



            'File.WriteAllText(txt_目标文件夹路径.Text & "\初始申请稿下载执行报告.txt", 初始申请稿下载执行报告, Encoding.UTF8)

        Catch ex As Exception
            MsgBox("错误: " & ex.Message, vbExclamation)
        End Try

        MsgBox("完成全部初始申请稿的下载操作！", vbInformation)

        sender.ForeColor = Color.Red

    End Sub

    Private Sub btn_打开发邮件窗口_Click(sender As Object, e As EventArgs)
        form_发送邮件.ShowDialog()
    End Sub

    Private Sub btn_发送邮件_Click(sender As Object, e As EventArgs) Handles btn_发送邮件.Click

        '' 先打开发送邮件的 form 
        'form_发送邮件.Show()

        ' 这里确立邮件服务器连接信息

        Dim strSmtpServer As String = "smtp.263.net"
        Dim strFrom As String = "qj@shbrg.com"
        Dim strFromPassword As String = "u7F&0Bsj"




        'Dim 邮件标题 = "审查意见通知书相关文件打包"

        Dim 邮件内容范文 = $"{vbCrLf}{vbCrLf}{vbCrLf}乔杰   专利代理师{vbCrLf}{vbCrLf}上海伯瑞杰知识产权代理有限公司（涉外代理机构）{vbCrLf}地址：上海市徐汇区田林路105号901室{vbCrLf}"
        邮件内容范文 &= $"网址：www.shbrg.com{vbCrLf}邮件：qj@shbrg.com  |  电话：021-6469 4553/8966 分机 808    {vbCrLf}上海 ● 浙江 ● 江苏 ● 内蒙"



        进度条_1.Minimum = 0
        进度条_1.Maximum = list_人员列表.Rows.Count
        进度条_1.Value = 0
        进度条_1.Step = 1


        ' 遍历 list_人员 中的每一行

        For Each row As DataGridViewRow In Me.list_人员列表.Rows
            '' 跳过新行（用户正在编辑的那行空白行）
            'If row.IsNewRow Then Continue For

            Dim 姓名 = CStr(row.Cells("name").Value)
            Dim 邮箱地址 = 姓名 & "<" & CStr(row.Cells("email").Value) & ">"

            ' 依据姓名，在目标文件夹中查找相关的子文件夹

            'Dim dirs = Directory.GetDirectories(txt_目标文件夹路径.Text, 姓名 & "*", SearchOption.TopDirectoryOnly)
            Dim dirs = New DirectoryInfo(txt_目标文件夹路径.Text).GetDirectories(姓名 & "*", SearchOption.TopDirectoryOnly)

            For Each 子目录 In dirs

                Try


                    ' 将子目录打包成 ZIP文件
                    'Imports System.IO.Compression
                    Dim zip打包路径 = Path.Combine(子目录.Parent.FullName, 子目录.Name & ".zip")
                    If File.Exists(zip打包路径) Then File.Delete(zip打包路径)
                    ZipFile.CreateFromDirectory(子目录.FullName, zip打包路径, CompressionLevel.Optimal, False)


                    ' 然后创建一个新邮件对象，然后发送出去

                    'form_发送邮件.txt_发送地址.Text = CStr(row.Cells("name").Value)   ' 列名
                    'form_发送邮件.txt_发送地址.Text &= "<" & CStr(row.Cells("email").Value) & ">"
                    'form_发送邮件.txt_邮件标题.Text = "审查意见通知书相关文件打包"
                    'form_发送邮件.txt_邮件内容.Text = CStr(row.Cells("name").Value) & form_发送邮件.txt_邮件内容.Text




                    Using mail As New MailMessage()
                        ' 发件人
                        mail.From = New MailAddress(strFrom)

                        ' 收件人 / 抄送
                        mail.To.Add(邮箱地址.Trim())
                        'If Not String.IsNullOrWhiteSpace(txt_抄送地址.Text) Then
                        '    mail.CC.Add(txt_抄送地址.Text.Trim())
                        'End If

                        ' 主题
                        mail.Subject = $"关于《{子目录.Name}》的通知暨相关文件打包".Trim()
                        mail.SubjectEncoding = Encoding.UTF8

                        ' 正文（RTF→HTML）
                        'Dim htmlBody As String = RTFToHTML($"{姓名}{邮件内容范文}")
                        'mail.Body = htmlBody

                        mail.Body = $"{姓名}老师，您好:{vbCrLf}近期来文中，与您相关的审查意见（补正）通知《{子目录.Name}》暨相关文件打包，发送给您，请注意接收！{邮件内容范文}"

                        ' 邮件内容范文 = $""

                        'mail.Body = $"{姓名}{邮件内容范文}"
                        'mail.IsBodyHtml = True
                        mail.IsBodyHtml = False
                        'mail.BodyEncoding = Encoding.UTF8

                        ' 附件
                        If 姓名 <> "王一琦" Then
                            '王老师特别要求，不需要附件
                            mail.Attachments.Add(New Attachment(zip打包路径))
                        End If


                        ' SMTP 配置
                        Using smtp As New SmtpClient(strSmtpServer, 587)
                            smtp.Credentials = New NetworkCredential(strFrom, strFromPassword)
                            smtp.EnableSsl = True
                            smtp.Timeout = 60 * 1000

                            smtp.Send(mail)
                        End Using
                    End Using

                    ' 完成邮件发送后，将zip包删除
                    If File.Exists(zip打包路径) Then File.Delete(zip打包路径)


                    'MessageBox.Show("邮件已成功发送！", "完成", MessageBoxButtons.OK, MessageBoxIcon.Information)

                Catch ex As Exception
                    MessageBox.Show($"在打包发送案件 {子目录} 时发生错误，错误码为：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
                End Try



            Next

            进度条_1.PerformStep()

        Next


        MsgBox("完成邮件发送！", vbInformation)

        sender.ForeColor = Color.Red

    End Sub

    Private Sub btn_批量下载申请文件_Click(sender As Object, e As EventArgs) Handles btn_批量下载申请文件.Click

        If MsgBox($"请确认已经登录【soopat】!{vbCrLf}是否继续？", vbYesNo) = vbNo Then Exit Sub


        Dim str_临时字符串1 = txt_信息2.Text

        ' 去除字符串末尾的无效字符
        'str_临时字符串1 = System.Text.RegularExpressions.Regex.Replace(str_临时字符串1, "\s+$", "")
        str_临时字符串1 = str_临时字符串1.TrimEnd({CChar(vbCr), CChar(vbLf), " "c})


        Dim arr_号码组 = str_临时字符串1.Split({vbCrLf, vbCr, vbLf}, StringSplitOptions.None)

        Dim 本地下载路径 = txt_申请文件批量下载本地路径.Text


        'dim 重定向地址 = ""
        'dim 重定向地址组 = ""
        Dim 下载状况报告 = ""

        Dim 下载案件成功数量 = 0
        Dim 下载案件失败数量 = 0


        进度条_1.Minimum = 0
        进度条_1.Maximum = arr_号码组.Count
        进度条_1.Value = 0
        进度条_1.Step = 1


        For Each 申请号 In arr_号码组

            'Dim 申请号 = 号码.Split("：")(0)
            'Dim 公开号 = 号码.Split("：")(1)

            ' edge浏览器 打开路径
            Dim edgePath = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"


            ' 用申请号来组织下载地址
            Dim 下载地址 = $"https://pro.soopat.com/Chinese/GetPdf?sqh={申请号.Substring(0, 12)}&sqgk=0&line=0"


            ' 采用 edge浏览器 打开“下载地址”
            If File.Exists(edgePath) Then
                Process.Start(edgePath, 下载地址)

                Do
                    For i = 0 To 50
                        ' 等待文件夹中出现以当前申请号开头的 PDF 文件
                        Dim 匹配文件 = Directory.GetFiles(本地下载路径, $"CN{申请号.Substring(0, 12)}*")

                        If 匹配文件.Length > 0 Then

                            ' 找到了，
                            下载案件成功数量 += 1
                            txt_信息2.Text = txt_信息2.Text.Replace(申请号 & vbCrLf, "")

                            ' 退出当前循环
                            Exit Do
                        Else
                            Thread.Sleep(100)
                        End If
                        'If File.Exists(文件路径) AndAlso 文件是否可访问(文件路径) Then
                        '    ' 再等待一小段时间确保文件完全写入
                        '    Thread.Sleep(1000)
                        '    Return True
                        'End If
                    Next i

                    If MsgBox("是否继续等待", vbYesNo Or vbQuestion) = vbNo Then

                        下载状况报告 &= "下载申请号为  " & 申请号 & " 的专利文献失败！" & vbCrLf
                        下载案件失败数量 += 1

                        MsgBox("请立即激活浏览器窗口！", vbInformation)

                        Thread.Sleep(3000)  ' 等待 1 秒（可根据网络调整）
                        ' 发送Ctrl+W组合键关闭当前标签页
                        SendKeys.Send("^(w)")

                        Exit Do

                    End If
                Loop

            Else
                ' 若找不到 Edge 路径，使用默认浏览器
                MsgBox("无法打开edge浏览器")
            End If

            进度条_1.PerformStep()

        Next

        下载状况报告 &= vbCrLf
        下载状况报告 &= "成功下载案件数量：" & 下载案件成功数量 & vbCrLf
        下载状况报告 &= "下载案件失败数量：" & 下载案件失败数量 & vbCrLf



        File.WriteAllText(本地下载路径 & "\公开申请文件下载状况报告" & Now.ToString("yyyyMMddHHmmss") & ".txt", 下载状况报告, Encoding.UTF8)


        'MsgBox($"完成批量下载！{vbCrLf}是否对下载的文件重命名？", vbYesNo Or vbInformation)



        ''Dim 本地下载路径 = txt_对比文件批量下载本地路径.Text


        'For Each f In Directory.GetFiles(本地下载路径)

        '    Dim oldName As String = Path.GetFileName(f)

        '    Dim str_前缀名 = oldName.Split("-")(0)

        '    For Each 号码 In arr_号码组
        '        Dim 申请号 = 号码.Split("：")(0)

        '        If str_前缀名 = 申请号 Then

        '            Dim 公开号 = 号码.Split("：")(1)

        '            Dim newPath = Path.Combine(本地下载路径, "（本案申请公开文件）" & oldName)


        '            '防止重名冲突
        '            If Not File.Exists(newPath) Then
        '                File.Move(f, newPath)
        '            End If

        '            Exit For

        '        End If

        '    Next

        'Next

        MsgBox("完成本案申请公开文件的批量下载，请参阅下载状况报告！", vbInformation)

        sender.ForeColor = Color.Red

    End Sub

    Private Sub btn_分配公开申请文件_Click(sender As Object, e As EventArgs) Handles btn_分配公开申请文件.Click



        ' 路径编辑框是否为空，若为空，则退出程序
        If txt_申请文件批量下载本地路径.Text = "" Then
            MsgBox("路径编辑框不能为空，请将安放有 申请文件批量下载 的文件夹拖放到编辑框中！")
            Exit Sub
        End If


        ' 将指定文件夹中的来文分配到每个审查意见文件包裹中

        ' 遍历目标文件夹中的每一个文件夹

        Try

            Dim 公开申请文件分配执行报告 = ""

            Dim dir_目标文件夹 As New DirectoryInfo(txt_目标文件夹路径.Text)
            Dim subDirs = dir_目标文件夹.GetDirectories


            进度条_1.Minimum = 0
            进度条_1.Maximum = subDirs.Count
            进度条_1.Value = 0
            进度条_1.Step = 1

            For Each subDir In subDirs

                ' 解析文件夹名，获取我方文号，申请号，等等信息


                Dim arrstr = Split(subDir.Name, "_")

                Dim temp_代理人 = arrstr(0)
                Dim temp_我方文号 = arrstr(1)
                Dim temp_申请号 = arrstr(2)
                Dim temp_发文日期 = arrstr(3)

                公开申请文件分配执行报告 &= "关于申请号 " & temp_申请号 & "：" & vbCrLf


                ' 根据申请号来查找下载的申请文件
                Dim dir_公开申请文件汇总 As New DirectoryInfo(txt_申请文件批量下载本地路径.Text)
                Dim files = dir_公开申请文件汇总.GetFiles($"CN{temp_申请号.Substring(0, Math.Min(12, temp_申请号.Length))}*")

                If files.Length > 0 Then

                    ' 遍历每一个文件
                    For Each file In files
                        ' 将该文件夹中发文日期与当前文件夹相匹配的PDF文件复制到审查意见文件包裹中
                        file.CopyTo(Path.Combine(subDir.FullName, $"（本申请公开文件）{file.Name}"), overwrite:=True)
                    Next

                Else
                    ' 未找到匹配的文件夹
                    公开申请文件分配执行报告 &= "没有找到匹配的申请公开文件，请确认一下!" & vbCrLf

                End If

                公开申请文件分配执行报告 &= vbCrLf


                进度条_1.PerformStep()

            Next

            File.WriteAllText(txt_目标文件夹路径.Text & "\本申请公开文件分配执行报告.txt", 公开申请文件分配执行报告, System.Text.Encoding.UTF8)

        Catch ex As Exception
            MsgBox("错误: " & ex.Message, vbExclamation)
        End Try

        MsgBox("完成全部公开申请文件分配操作！")

        sender.ForeColor = Color.Red

    End Sub



    Private Sub btn_下载前期提交答复_Click(sender As Object, e As EventArgs) Handles btn_下载前期提交答复.Click

        ' 路径编辑框是否为空，若为空，则退出程序
        If txt_目标文件夹路径.Text = "" Then
            MsgBox("目标文件夹路径编辑框不能为空，请将安放有 所有代理人案件信息 的文件夹拖放到编辑框中！")
            Exit Sub
        End If


        ' 遍历目标文件夹中的每一个文件夹

        Try

            Dim 先前提交答复下载执行报告 = ""

            ' 先组织共享服务器地址

            Dim str_共享服务器 = "\\1-pc\伯瑞杰共享中心\"

            Dim str_电子申请文件路径 = Path.Combine(str_共享服务器, "电子申请")



            Dim dir_目标文件夹 As New DirectoryInfo(txt_目标文件夹路径.Text)
            Dim subDirs = dir_目标文件夹.GetDirectories

            Dim str_提交答复文件夹路径 = ""


            '进度条_1.Value =
            进度条_1.Minimum = 0
            进度条_1.Maximum = subDirs.Count
            进度条_1.Value = 0
            进度条_1.Step = 1



            'Dim counter As Integer = 0

            For Each subDir In subDirs

                Try


                    'counter += 1

                    'lab_下载申请稿计数.Text = counter.ToString

                    'lab_下载申请稿计数.Refresh()          '立即重绘控件
                    'Application.DoEvents()               '让 UI 线程处理一次消息队列

                    ' 提取申请号，并获取申请年份
                    Dim 十二位的申请号 = subDir.Name.Split("_")(2).Substring(0, 12)
                    Dim 申请年份 = 十二位的申请号.Substring(0, 4)


                    ' 从申请年份开始查，遍历每一年份，至今

                    For i年份 = CInt(申请年份) To Now.Year



                        If i年份 = Now.Year Then

                            'str_提交答复文件夹路径 = Path.Combine(str_电子申请文件路径 & "\" & Now.Year)
                            str_提交答复文件夹路径 = Path.Combine(str_电子申请文件路径, i年份 & "年电子申请")

                        Else
                            'str_提交答复文件夹路径 = Path.Combine(str_电子申请文件路径 & "\" & Now.Year)
                            str_提交答复文件夹路径 = Path.Combine(str_电子申请文件路径, "往年专利存档文件", i年份)

                        End If

                        If i年份 = 2024 Or i年份 >= 2018 And i年份 <= 2022 Then
                            str_提交答复文件夹路径 &= "年存档"
                        End If


                        If i年份 = 2023 Then
                            str_提交答复文件夹路径 &= "年电子申请"
                        End If


                        'If i年份 = 2024 Or (i年份 >= 2012 And i年份 <= 2017) Then
                        If i年份 >= 2012 And i年份 <= 2017 Then
                            str_提交答复文件夹路径 &= "存档"
                        End If



                        If i年份 = 2024 Or i年份 >= 2017 And i年份 <= 2022 Then
                            str_提交答复文件夹路径 &= "\" & i年份 & "年电子申请"
                        End If


                        str_提交答复文件夹路径 &= "\" & "【已提交】补正实审"

                        ' 测试一下，文件夹路径是否存在
                        If Not Directory.Exists(str_提交答复文件夹路径) Then
                            MsgBox("文件夹不存在，请重新修改程序", vbExclamation)
                            Exit Sub
                        End If

                        ' \\1-pc\伯瑞杰共享中心\电子申请\往年专利存档文件\2024年存档\2024年电子申请

                        Dim dir_提交答复文件夹路径 As New DirectoryInfo(str_提交答复文件夹路径)

                        ' 自此完成了 文件夹路径 的组织

                        ' 接下来，在“str_提交答复文件夹路径”中查找符合发明名称的案子，找到了就下载，没有找到的话就算了

                        For Each file In dir_提交答复文件夹路径.GetFiles("*" & 十二位的申请号 & "*")

                            Dim 目标路径_先前提交答复 = Path.Combine(subDir.FullName, "先前提交答复")

                            If Not Directory.Exists(目标路径_先前提交答复) Then
                                Directory.CreateDirectory(目标路径_先前提交答复)
                            End If

                            file.CopyTo(Path.Combine(目标路径_先前提交答复, file.Name), True)

                        Next

                        ' 针对每一个月份，再进行检索

                        For Each 月份文件夹 In dir_提交答复文件夹路径.GetDirectories()

                            For Each file In 月份文件夹.GetFiles("*" & 十二位的申请号 & "*")

                                Dim 目标路径_先前提交答复 = Path.Combine(subDir.FullName, "先前提交答复")

                                If Not Directory.Exists(目标路径_先前提交答复) Then
                                    Directory.CreateDirectory(目标路径_先前提交答复)
                                End If

                                file.CopyTo(Path.Combine(目标路径_先前提交答复, file.Name), True)

                            Next

                        Next

                    Next i年份

                Catch ex As Exception
                    MsgBox("错误: " & ex.Message, vbExclamation)

                End Try

                进度条_1.PerformStep()
                '进度条_1.Refresh()

            Next



            File.WriteAllText(txt_目标文件夹路径.Text & "\先前提交答复下载执行报告.txt", 先前提交答复下载执行报告, Encoding.UTF8)

        Catch ex As Exception
            MsgBox("错误: " & ex.Message, vbExclamation)
        End Try

        MsgBox("完成全部先前提交答复稿的下载操作！", vbInformation)

        sender.ForeColor = Color.Red

    End Sub

    Private Sub btn_重置按钮颜色_Click(sender As Object, e As EventArgs) Handles btn_重置按钮颜色.Click

        Me.btn_下载初始申请稿.ForeColor = Color.Black
        Me.btn_下载前期提交答复.ForeColor = Color.Black
        Me.btn_分配公开申请文件.ForeColor = Color.Black
        Me.btn_分配对比文件.ForeColor = Color.Black
        Me.btn_分配来文.ForeColor = Color.Black
        Me.btn_处理表格.ForeColor = Color.Black
        Me.btn_发送邮件.ForeColor = Color.Black
        Me.btn_批量下载专利.ForeColor = Color.Black
        Me.btn_批量下载申请文件.ForeColor = Color.Black
        Me.btn_提取公开号信息.ForeColor = Color.Black
        Me.btn_提取来文信息.ForeColor = Color.Black

    End Sub

    Private Sub btn_处理表格_维护_Click(sender As Object, e As EventArgs) Handles btn_处理表格_维护.Click

        ' 先确认一下，是否已经完成汇总来文下载，否则退出程序
        If MsgBox($"请确认，是否已经完成汇总来文下载？{vbCrLf}是否继续？", vbYesNo) = vbNo Then
            ' 退出程序
            Exit Sub
        End If



        ' 路径编辑框是否为空，若为空，则退出程序
        If txt_目标文件夹路径_维护.Text = "" Then
            MsgBox("路径编辑框不能为空，请将安放有 来文表格 的文件夹拖放到编辑框中！")
            Exit Sub
        End If

        If Path.Exists(txt_目标文件夹路径_维护.Text) Then
            ' 改文件夹名称为当前日期
            If MsgBox("是否将文件夹改名为当前的 年月日 ？", vbYesNo, "修改文件夹名") = vbYes Then


                Dim oldFullPath = txt_目标文件夹路径_维护.Text
                Dim newFolderName = Format(Now, "yyyy年MM月dd日") & "维护老师相关"
                Dim newFullPath = Path.Combine(Path.GetDirectoryName(oldFullPath), newFolderName)

                If oldFullPath <> newFullPath Then

                    If Not Path.Exists(newFullPath) Then

                        Directory.Move(oldFullPath, newFullPath)

                        txt_目标文件夹路径_维护.Text = newFullPath

                        txt_目标文件夹路径_维护.Refresh()

                    Else

                        MsgBox("要修改的文件夹路径已经存在，不能修改！")

                    End If

                End If

            End If
        Else
            MsgBox("路径编辑框中的路径不存在，请重新设置路径！")
            Exit Sub
        End If






        ' 先清空信息框
        'txt_信息1_维护.Text = ""
        'txt_信息2.Text = ""


        '' 先获取信息框1中的字符串
        'If MsgBox("是否刷新信息框2？", vbYesNo) = vbYes Then
        '    txt_信息2.Text = txt_信息1.Text.TrimEnd({CChar(vbCr), CChar(vbLf), " "c})

        '    Dim arr_临时字符串数组 = txt_信息2.Text.Split(vbCrLf)

        '    Dim result = arr_临时字符串数组.Where(Function(s) s(4) = "1"c).ToList()

        '    txt_信息2.Text = String.Join(vbCrLf, result)

        'End If


        '最终需要在桌面上输出“来文表格检索执行报告.txt”文本文件
        Dim 来文表格检索执行报告 = ""


        Dim excelApp As Object
        Dim excelWorkbook As Object
        Dim excelSheet As Object
        Dim 主操作文件夹路径 = txt_目标文件夹路径_维护.Text


        Try


            ' 查找文件名包含"来文"的文件（不递归子文件夹）
            Dim files() As String
            files = Directory.GetFiles(主操作文件夹路径, "*来文*.xls*")

            If files.Count <> 1 Then
                MsgBox("文件夹中没有或者存在多个来文表格文件，请确认一下？" & vbCrLf & "本次程序结束执行！", vbInformation)
                Exit Sub
            End If


            'Console.WriteLine(files(0))

            Dim filepath = files(0)


            ' 先做预备工作

            Dim records As New List(Of String())

            ' 复制表头到记录数组的第一行
            records.Add(New String() {"我方文号", "申请号", "案件名称", "文件名称", "发文日期", "申请日", "申请人", "案源人", "代理人", "是否优先审查", "是否快速预审"})  ' 正常运行
            'Dim recordCount As Integer = 0

            ''records_1(i) = arr_直接规定表头(i)


            '' 声明并初始化表头数组
            'Dim arr_直接规定表头 As String() = New String() {"我方文号", "申请号", "案件名称", "文件名称", "发文日期", "申请日", "申请人", "案源人", "代理人", "是否优先审查", "是否快速预审"}

            ' 定义表头序号常量
            Dim 表头序号_我方文号 = 0
            Dim 表头序号_申请号 = 1
            Dim 表头序号_案件名称 = 2
            Dim 表头序号_文件名称 = 3
            Dim 表头序号_发文日期 = 4
            Dim 表头序号_申请日 = 5
            Dim 表头序号_申请人 = 6
            Dim 表头序号_案源人 = 7
            Dim 表头序号_代理人 = 8
            Dim 表头序号_优先审查 = 9
            Dim 表头序号_快速预审 = 10

            '' 获取表头数量
            'Dim n_表头数 As Integer = arr_直接规定表头.Length

            '' 初始化记录数组 (注意：VB.NET数组默认从0开始，而VBA默认从1开始)
            'Dim records_1(n_表头数 - 1) As String









            ' 尝试创建 Excel 应用实例，类似 VBA 里的 CreateObject("Excel.Application")
            excelApp = CreateObject("Excel.Application")

            ' 若需要可见，可设置，比如调试时设为 True 方便看操作过程
            excelApp.Visible = False

            If filepath <> "" Then
                ' 打开指定工作簿，类似 VBA 里的 Workbooks.Open
                excelWorkbook = excelApp.Workbooks.Open(filepath)
            Else
                MessageBox.Show("请指定一个有效的 Excel 文件路径！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                Exit Sub
            End If

            ' 获取活动工作表，类似 VBA 里的 ActiveSheet
            excelSheet = excelWorkbook.ActiveSheet

            '   **********************************
            '   ***     至此，已经完成了文件  ****
            '   ***     打开                  ****
            '   **********************************


            '' 这里可以添加对工作表的读写操作，示例：读取 A1 单元格值并显示
            'Dim cellValue As Object = excelSheet.Cells(1, 1).Value
            'MessageBox.Show($"A1 单元格的值为：{cellValue}", "结果", MessageBoxButtons.OK, MessageBoxIcon.Information)

            '' 示例：写入数据到 B1 单元格
            'excelSheet.Cells(3, 2).Value = "VB.NET 写入的数据"



            ' 在这里判断第2行的单元格内容是否与“arr_直接规定表头”匹配
            For i = 0 To 10
                ' 进行表头匹配判断（注意：COM对象取值可能为Nothing，需处理）
                Dim cellValue = excelSheet.Cells(2, i + 1).Value
                Dim cellText = If(cellValue Is Nothing, "", cellValue.ToString)



                'If arr_直接规定表头(i) <> cellText Then
                If records(0)(i) <> cellText Then
                    ' 表头不匹配时提示并退出
                    MessageBox.Show("设定表头与实际表头不匹配，程序不能继续执行，请确认后再执行！" & Environment.NewLine & "目前退出程序！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)

                    ' 关闭工作簿和Excel应用
                    excelWorkbook.Close(SaveChanges:=False)
                    excelApp.Quit

                    ' 释放资源
                    Marshal.ReleaseComObject(excelSheet)
                    Marshal.ReleaseComObject(excelWorkbook)
                    Marshal.ReleaseComObject(excelApp)
                    excelSheet = Nothing
                    excelWorkbook = Nothing
                    excelApp = Nothing
                    GC.Collect()

                    Exit Sub
                End If
            Next i

            ' 若匹配无误，修改表头数组中的对应值
            records(0)(9) = "优先审查"
            records(0)(10) = "快速预审"


            'Dim lastRow As Integer = excelSheet.Cells(excelSheet.Rows.Count, 1).End(Excel.XlDirection.xlUp).Row
            'Dim lastRow As Integer = excelSheet.UsedRange.Rows.Count

            ' 在 A 列中查找单元格内容为“我方文号”的单元格（注意：必须以有效的最后一行为限，即：excelSheet.UsedRange.Rows.Count），
            ' 若查找到的话，则将该单元格所在行确定为本次载入表格数据的下限



            ' 查找区域从 A3 开始直到 A 列最后一行
            Dim lastRow As Long = excelSheet.UsedRange.Row + excelSheet.UsedRange.Rows.Count - 1
            Dim rngFound As Excel.Range = excelSheet.Range("A3", excelSheet.Cells(lastRow, "A")).Find(What:="我方文号",
                    LookIn:=Excel.XlFindLookIn.xlValues,
                    LookAt:=Excel.XlLookAt.xlWhole,
                    MatchCase:=False)

            lastRow = rngFound.Row - 1

            'MsgBox($"中间文件的最后一行为{lastRow}")


            ' 将 xlsx 表格中所有的【中间文件】内容全部读入到二维数组中

            For rowNumber = 3 To lastRow
                ' 获取单元格值并处理可能的空值
                'Dim cellValue As Object = excelSheet.Cells(rowNumber, 表头序号_代理人+1).Value
                'Dim agentName As String = If(cellValue Is Nothing, "", cellValue.ToString())

                'recordCount += 1

                ' 动态调整二维数组大小（VB.NET中需创建新数组并复制）
                records.Add(New String(10) {})


                ' 复制当前行数据到记录数组
                For colNumber = 0 To UBound(records(0))
                    ' 获取单元格值并处理空值
                    Dim value = excelSheet.Cells(rowNumber, colNumber + 1).Value
                    records(records.Count - 1)(colNumber) = If(value Is Nothing, "", value.ToString)
                Next colNumber

            Next rowNumber




            ' 接下来针对每一“中间文件”记录进行操作
            If MessageBox.Show("是否对中间文件进行检索？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = vbYes Then

                来文表格检索执行报告 = 来文表格检索执行报告 & "开始查找中间文件：" & vbCrLf & vbCrLf

                进度条_1.Minimum = 0
                进度条_1.Maximum = records.Count - 1
                进度条_1.Value = 0
                进度条_1.Step = 1


                Dim obj_来文汇总文件夹 As New DirectoryInfo(txt_来文汇总路径_维护.Text)

                Dim subDirs

                Dim path_维护人文件夹 = ""


                For i = 1 To records.Count - 1

                    ' 确定维护人文件夹
                    If records(i)(表头序号_案源人) = "" Then
                        path_维护人文件夹 = Path.Combine(主操作文件夹路径, "江艳珠")
                    Else
                        path_维护人文件夹 = Path.Combine(主操作文件夹路径, records(i)(表头序号_案源人))
                    End If

                    ' 判断维护人文件夹是否已经建立

                    If Not Path.Exists(path_维护人文件夹) Then Directory.CreateDirectory(path_维护人文件夹)

                    ' 先依据“我方文号”定位文件夹，并测试一下来文是否存在，
                    ' 若来文不存在提出警示，并写入报告中，
                    ' 若来文存在，将文件夹中对应发文日期和来文名称的文件复制到维护人文件夹中，
                    ' 最后根据要求来修改文件名称

                    subDirs = obj_来文汇总文件夹.GetDirectories(records(i)(表头序号_我方文号))

                    If subDirs.Length <> 1 Then
                        Dim 错误信息 = $"在处理 {records(i)(表头序号_案源人)}_{records(i)(表头序号_我方文号)} 案件时出错，一共找到了{subDirs.Length}个文件夹！"
                        MsgBox(错误信息, vbExclamation)
                        来文表格检索执行报告 &= vbCrLf & 错误信息 & vbCrLf
                        Continue For
                    End If

                    ' 在确定的来文源文件夹中，依据文件名称来查找所有的 PDF 文件
                    Dim file As FileInfo
                    For Each file In subDirs(0).getfiles($"{records(i)(表头序号_文件名称)}*")
                        ' 查一下，文件名称中的“文件名称”和“发文日”是否与表格记录中的一致，若是的话，则可以确定
                        Dim arr_filename = file.Name.Split("_")
                        If records(i)(表头序号_文件名称) = arr_filename(0) And CDate(records(i)(表头序号_发文日期)) = CDate(arr_filename(1)) Then

                            ' 组织文件存储目标路径
                            Dim path_文件存储目标路径 = ""

                            If records(i)(表头序号_申请人).Contains("中山医院") Then
                                path_文件存储目标路径 &= $"{Format(CDate(records(i)(表头序号_发文日期)), "yyyy MM dd")}"
                                path_文件存储目标路径 &= $" {records(i)(表头序号_案件名称).Replace("\", "-").Replace("/", "-")}"
                                path_文件存储目标路径 &= $" {records(i)(表头序号_申请号).Replace(".", "")}"
                                path_文件存储目标路径 &= $" {records(i)(表头序号_文件名称).Replace("\", "-").Replace("/", "-")}.pdf"
                            Else
                                path_文件存储目标路径 &= $"{records(i)(表头序号_申请人).Replace("\", "-").Replace("/", "-")}"
                                path_文件存储目标路径 &= $"+{records(i)(表头序号_申请号).Replace("\", "-").Replace("/", "-")}"
                                path_文件存储目标路径 &= $"+{records(i)(表头序号_文件名称).Replace("\", "-").Replace("/", "-")}.pdf"

                            End If



                            ' 去除路径中所有不能用于文件名称的非法字符
                            path_文件存储目标路径 = String.Concat(path_文件存储目标路径.Where(Function(c) Not Path.GetInvalidFileNameChars().Contains(c)))

                            path_文件存储目标路径 = Path.Combine(path_维护人文件夹, path_文件存储目标路径)


                            ' 将该文件复制到“path_维护人文件夹”中
                            file.CopyTo(path_文件存储目标路径, overwrite:=True)

                            ' 然后，退出当前 for 循环
                            Exit For

                        End If

                    Next



                    'If InStr(records(i)(表头序号_文件名称), "审查意见") > 0 Or InStr(records(i)(表头序号_文件名称), "补正") > 0 Then

                    '    'report = report & records_2(i, 表头序号_申请号) & "，" & records_2(i, 表头序号_案件名称) & "：" & vbCrLf
                    '    来文表格检索执行报告 = 来文表格检索执行报告 & records(i)(表头序号_申请号) & "，" & records(i)(表头序号_案件名称) & "：" & vbCrLf

                    '    ' 在信息窗口中，将检索得出的所有案件的申请号列出
                    '    txt_信息1.Text &= records(i)(表头序号_申请号) & vbCrLf

                    '    ' 判断是否为发明专利，并且不是补正通知，然后将申请号放入到 信息框2 中，准备下载专利文献
                    '    ' 如果不是发明专利，或者，是补正通知的话，没用公开文件可以下载
                    '    If records(i)(表头序号_申请号).Substring(4, 1) = 1 And Not records(i)(表头序号_文件名称).Contains("补正") Then
                    '        txt_信息2.Text &= records(i)(表头序号_申请号) & vbCrLf
                    '    End If



                    '    ' 构建文件夹，以“文号”，“申请号”，“代理人”结合作为文件夹名称
                    '    Dim str_答复文件夹 As String

                    '    str_答复文件夹 = 主操作文件夹路径 & "\"
                    '    str_答复文件夹 &= records(i)(表头序号_代理人)
                    '    str_答复文件夹 &= "_" & records(i)(表头序号_我方文号)
                    '    str_答复文件夹 &= "_" & Regex.Replace(records(i)(表头序号_申请号), "[^\d]", "")
                    '    str_答复文件夹 &= "_" & Format(CDate(records(i)(表头序号_发文日期)), "yyyy-MM-dd")

                    '    ' 以下的代码表示，去除所有的不能用于文件名的字符，诸如斜杠
                    '    str_答复文件夹 &= "_" & Regex.Replace(records(i)(表头序号_案件名称), "[" & Regex.Escape(New String(Path.GetInvalidFileNameChars)) & "]", "")



                    '    If Not Directory.Exists(str_答复文件夹) Then
                    '        Directory.CreateDirectory(str_答复文件夹)
                    '        'Console.WriteLine("文件夹创建成功")
                    '    End If


                    '    ' 在刚刚构建的文件夹中创建一个“案件信息”的文本文件，输出所有的表项内容

                    '    Dim str_案件信息 = ""

                    '    str_案件信息 &= "我方文号：" & records(i)(表头序号_我方文号) & vbCrLf
                    '    str_案件信息 &= "来文名称：" & records(i)(表头序号_文件名称) & vbCrLf
                    '    str_案件信息 &= "申请号：" & records(i)(表头序号_申请号) & vbCrLf
                    '    str_案件信息 &= "案件名称：" & records(i)(表头序号_案件名称) & vbCrLf
                    '    str_案件信息 &= "发文日期：" & records(i)(表头序号_发文日期) & vbCrLf
                    '    str_案件信息 &= "申请日：" & records(i)(表头序号_申请日) & vbCrLf
                    '    str_案件信息 &= "申请人：" & records(i)(表头序号_申请人) & vbCrLf
                    '    str_案件信息 &= "维护人：" & records(i)(表头序号_案源人) & vbCrLf
                    '    str_案件信息 &= "代理人：" & records(i)(表头序号_代理人) & vbCrLf
                    '    str_案件信息 &= "优先审查：" & records(i)(表头序号_优先审查) & vbCrLf
                    '    str_案件信息 &= "快速预审：" & records(i)(表头序号_快速预审) & vbCrLf

                    '    File.WriteAllText(Path.Combine(str_答复文件夹, "案件信息.txt"), str_案件信息, Encoding.UTF8)

                    'End If

                    进度条_1.PerformStep()

                Next

            End If


            File.WriteAllText(主操作文件夹路径 & "\来文表格检索执行报告.txt", 来文表格检索执行报告, Encoding.UTF8)

        Catch ex As Exception
            MessageBox.Show($"操作过程中出现错误：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            ' 释放资源，非常关键，避免 COM 对象残留导致问题
            If excelSheet IsNot Nothing Then
                Marshal.ReleaseComObject(excelSheet)
                excelSheet = Nothing
            End If
            If excelWorkbook IsNot Nothing Then
                excelWorkbook.Close
                Marshal.ReleaseComObject(excelWorkbook)
                excelWorkbook = Nothing
            End If
            If excelApp IsNot Nothing Then
                excelApp.Quit
                Marshal.ReleaseComObject(excelApp)
                excelApp = Nothing
            End If
            GC.Collect() ' 强制垃圾回收，协助释放资源

            MsgBox("完成全部表格信息处理！", vbInformation)

        End Try

        'sender.ForeColor = Color.Red




    End Sub
End Class





' 简单的实体类
Public Class Person
    Public Property Name As String
    Public Property Email As String
End Class